<?php
/**
 * Created By PhpStorm
 * Author: patrick wu
 * Date: 2020/10/12
 * Time: 20:03
 */
namespace App\Service\Api;

use App\Http\Model\Mysql\OrderIntegralModel;
use App\Http\Model\Mysql\ProductModel;
use App\Http\Model\Mysql\UserAddressModel;
use App\Http\Model\Mysql\UserIntegralModel;
use App\Http\Model\Mysql\UserModel;
use Illuminate\Support\Facades\Redis;
use App\Constant\RedisKeyConstant;
use App\Http\Model\Mysql\ProductIntegralModel;
use Carbon\Carbon;

class CartService extends BaseService
{
    /**
     * 添加到购物车
     * @param int $good_id      商品ID
     * @param int $spec_id      属性ID
     * @param int $good_number  商品数量
     * @return array
     */
    public function cartCollect(int $good_id, int $spec_id, int $good_number)
    {
        $user_info  =   request()->post('api_user');
        $user_id    =   $user_info['user_id'];

        /**
         * 查看规格内容
         */
        $cart['good_id']    =   $good_id;
        $cart['spec_id']    =   $spec_id;
        $cart['good_number']=   $good_number;
        $cart['unique_id']  =   createUniqueID();
        $cart['collect_at'] =   Carbon::now()->timestamp;

        /**
         * 查看是否有存在的商品
         */
        $all_collect    =   Redis::ZRANGE(RedisKeyConstant::USER_COLLECT_CART . $user_id, 0, -1);
        if (!empty($all_collect)) {
            foreach ($all_collect as $item) {
                $collect_info   =   json_decode($item, true);
                if ($collect_info['good_id'] == $cart['good_id'] && $collect_info['spec_id'] == $cart['spec_id']) {
                    $cart['good_number']    +=  $collect_info['good_number'];
                    Redis::ZREM(RedisKeyConstant::USER_COLLECT_CART . $user_id, $item);
                }
            }
        }

        //保存
        $result =   Redis::ZADD(RedisKeyConstant::USER_COLLECT_CART . $user_id, $cart['collect_at'], json_encode($cart, JSON_UNESCAPED_UNICODE));
        if ($result) {
            return [true, '添加成功'];
        } else {
            return [false, '添加失败'];
        }
    }

    /**
     * 用户购物车列表
     * @return array
     */
    public function cartList()
    {
        $user_info  =   request()->post('api_user');
        $user_id    =   $user_info['user_id'];

        $all_collect    =   Redis::ZREVRANGE(RedisKeyConstant::USER_COLLECT_CART . $user_id, 0, -1);
        $total_collect  =   [];
        $total_number   =   0;
        if (!empty($all_collect)) {
            foreach ($all_collect as $item) {
                $collect_info   =   json_decode($item,true);
                $spec_info  =   ProductModel::with([
                                    'specs'  =>  function ($query) use($collect_info) {
                                        $query->where(['id' => $collect_info['spec_id'], 'product_id' => $collect_info['good_id']])->select(['product_id', 'attr_list', 'sell_price', 'original_price', 'stock', 'spec_pic', 'sku_code']);
                                    }
                                ])->where(['id' => $collect_info['good_id']])->select(['id', 'name', 'cover_pic', 'sell_price', 'is_shelf', 'stock', 'unique_id'])->first();

                if(empty($spec_info)) {
                    continue;
                }
                $spec_info              =   $spec_info->toArray();

                //商品规格的处理
                $spec_info['specs']     =   array_map(function (&$item) {
                    $item['attr_value'] =   !empty($item['attr_list']) ? array_values(json_decode($item['attr_list'], true)) : [];
                    return $item;
                }, $spec_info['specs']);

                $spec_info['specs'] =   empty($spec_info['specs']) ? [] : array_pop($spec_info['specs']);

                $total_collect[]    =   array_merge($collect_info, $spec_info);
                $total_number      +=   $collect_info['good_number'];
            }
        }
        return [true, [
            'cart_list' =>  $total_collect,
            'cart_number'=> $total_number
        ]];
    }

    /**
     * 用户删除指定购物车信息
     * @param array $collect_at  添加时间
     * @return array
     */
    public function cartDelete(array $collect_at)
    {
        $user_info  =   request()->post('api_user');
        $user_id    =   $user_info['user_id'];

        foreach ($collect_at as $item) {
            Redis::ZREMRANGEBYSCORE(RedisKeyConstant::USER_COLLECT_CART . $user_id, $item, $item);
        }
        return [true, '删除成功'];
    }

    /**
     * 用户修改购物车数量
     * @param int $collect_at  添加时间
     * @param int $good_number 商品数量
     * @return array
     */
    public function cartModify(int $collect_at, int $good_number)
    {
        $user_info  =   request()->post('api_user');
        $user_id    =   $user_info['user_id'];

        $range_info =   Redis::ZRANGEBYSCORE(RedisKeyConstant::USER_COLLECT_CART . $user_id, $collect_at, $collect_at);
        if (empty($range_info)) {
            return [false, '购物车数据不存在'];
        }

        $single_info    =   json_decode(array_pop($range_info), true);
        $collect_info['good_id']    =   $single_info['good_id'];
        $collect_info['spec_id']    =   $single_info['spec_id'];
        $collect_info['good_number']=   $good_number;
        $collect_info['unique_id']  =   $single_info['unique_id'];
        $collect_info['collect_at'] =   Carbon::now()->timestamp;

        Redis::ZREMRANGEBYSCORE(RedisKeyConstant::USER_COLLECT_CART . $user_id, $collect_at, $collect_at);
        $result =   Redis::ZADD(RedisKeyConstant::USER_COLLECT_CART . $user_id, $collect_info['collect_at'], json_encode($collect_info, JSON_UNESCAPED_UNICODE));

        if ($result) {
            return [true, '修改成功'];
        } else {
            return [false, '修改失败'];
        }
    }

    /**
     * 清除指定购物车数据
     * @param array $good_array  指定商品数据
     * @param int|null $user_id  用户ID
     * @return bool
     */
    public function cartClear(array $good_array, int $user_id = NULL)
    {
        if (is_null($user_id)) {
            $user_info  =   request()->post('api_user');
            $user_id    =   $user_info['user_id'];
        }

        $all_collect    =   Redis::ZREVRANGE(RedisKeyConstant::USER_COLLECT_CART . $user_id, 0, -1);
        if (!empty($all_collect)) {
            foreach ($all_collect as $item) {
                $collect_info   =   json_decode($item, true);
                foreach ($good_array as $cart) {
                    if ($collect_info['good_id'] == $cart['good_id'] && $collect_info['spec_id'] == $cart['spec_id']) {
                        Redis::ZREM(RedisKeyConstant::USER_COLLECT_CART . $user_id, $item);
                    }
                }
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 兑换积分
     * @param int $good_id
     * @param int $spec_id
     * @param int $number
     * @param int|null $address_id
     * @return array
     */
    public function cartIntegral(int $good_id, int $spec_id, int $number, int $address_id = null)
    {
        $single_integral    =   ProductIntegralModel::where(['good_id' => $good_id, 'spec_id' => $spec_id, 'is_shelf' => 1])->select(['id', 'good_id', 'spec_id', 'integral', 'is_vip'])->first();
        if (empty($single_integral)) {
            return [false, '商品不存在'];
        }

        $user_info  =   auth('api')->user();
        $before     =   $user_info->integral;
        if ($single_integral->is_vip == 1 && $user_info->level == 0) {
            return [false, '无权购买'];
        }

        if ($before < $single_integral->integral * $number) {
            return [false, '积分不足'];
        }

        /**
         * 获取用户地址信息
         */
        $address['user_id'] =   $user_info->uid;
        if (is_null($address_id)) {
            $address['is_default']  =   1;
        } else {
            $address['id']      =   $address_id;
        }
        $address['is_delete']   =   UserAddressModel::NOT_DELETE;
        $address_info   =   UserAddressModel::where($address)->select(['user_name', 'tel_number', 'province', 'city', 'area', 'address', 'postal_code'])->first();
        if (empty($address_info)) {
            return [false, '请选择正确地址'];
        }

        $now_time       =   Carbon::now()->timestamp;
        $order_prefix   =   $user_info->uid . $now_time;
        $order_number   =   $order_prefix . (createRandomNumber(24  - strlen($order_prefix)));
        $normal_order['user_id']        =    $user_info->uid;
        $normal_order['order_no']       =    $order_number;
        $normal_order['good_id']        =    $good_id;
        $normal_order['spec_id']        =    $spec_id;
        $normal_order['good_number']    =    $number;
        $normal_order['total_integral'] =    $single_integral->integral * $number;
        $normal_order['buyer_name']     =    $address_info['user_name'];
        $normal_order['buyer_phone']    =    $address_info['tel_number'];
        $normal_order['buyer_province'] =    $address_info['province'];
        $normal_order['buyer_city']     =    $address_info['city'];
        $normal_order['buyer_area']     =    $address_info['area'];
        $normal_order['buyer_address']  =    $address_info['address'];

        $order_info =   OrderIntegralModel::create($normal_order);

        $after  =   $before - $normal_order['total_integral'];
        $result =   UserModel::where(['uid' => $user_info->uid])->update(['integral' => $after]);
        if ($result) {
            $order_info->is_pay   =   1;
            $order_info->pay_time =   Carbon::now()->timestamp;
            $order_info->save();

            $income =   UserIntegralModel::create([
                            'user_id'   =>  $user_info->uid,
                            'before'    =>  $before,
                            'after'     =>  $after,
                            'integral'  =>  $normal_order['total_integral'],
                            'type'      =>  1,
                            'reason'    =>  0,
                            'order_id'  =>  $order_info->id
                        ]);

            if ($income) {
                return [true, '兑换成功'];
            } else {
                return [false, '兑换失败'];
            }
        } else {
            return [false, '兑换失败'];
        }
    }
}
